package cn.ocars.playgame.pencilstudy.ui.components

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.graphics.PathMeasure
import android.opengl.GLES20
import android.opengl.GLSurfaceView
import android.opengl.Matrix
import android.view.MotionEvent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.input.motionprediction.MotionEventPredictor
import cn.ocars.playgame.pencilstudy.ui.theme.PrimaryBlue
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.FloatBuffer
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10
import kotlin.math.abs
import kotlin.math.sqrt

/**
 * 低延迟书写卡片组件
 * 使用OpenGL ES和MotionEventPredictor实现极低延迟的书写体验
 */
@Composable
fun LowLatencyWritingCard(
    character: String,
    onWritingComplete: (WritingScoreEvaluator.ScoreResult) -> Unit,
    modifier: Modifier = Modifier,
    onClearClick: (() -> Unit)? = null
) {
    val context = LocalContext.current
    
    // 自动获取字符数据
    val characterData = remember(character) {
        val data = CharacterDataProvider.getCharacterData(character)
        println("组件初始化: 字符=$character, 获取到的数据=${data?.character}, 笔画数=${data?.getTotalStrokes()}")
        
        // 验证具体字符的笔画数
        when (character) {
            "1" -> println("数字1应该有1笔，实际有${data?.getTotalStrokes()}笔")
            "一" -> println("汉字一应该有1笔，实际有${data?.getTotalStrokes()}笔")
            "人" -> println("汉字人应该有2笔，实际有${data?.getTotalStrokes()}笔")
            "大" -> println("汉字大应该有3笔，实际有${data?.getTotalStrokes()}笔")
        }
        
        data
    }
    
    val renderer = remember { 
        val glView = LowLatencyGLSurfaceView(context)
        LowLatencyWritingRenderer(glView, context, null, onWritingComplete)
    }
    
    // 当字符数据变化时更新渲染器
    LaunchedEffect(characterData) {
        renderer.updateCharacterData(characterData)
    }
    
    Box(
        modifier = modifier.size(150.dp),
        contentAlignment = Alignment.Center
    ) {
        AndroidView(
            modifier = Modifier.fillMaxSize(),
            factory = {
                val glView = LowLatencyGLSurfaceView(context)
                glView.setRenderer(renderer)
                renderer.setGLView(glView)
                
                // 确保字符数据正确传递
                renderer.updateCharacterData(characterData)
                
                // 设置渲染模式为RENDERMODE_WHEN_DIRTY，只在需要时渲染
                glView.renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY
                
                // 设置触摸事件监听器
                glView.setOnTouchListener { view, event ->
                    renderer.handleTouchEvent(event, view.width, view.height)
                    true
                }
                
                glView
            }
        )
        
        // 橡皮图标
        androidx.compose.material3.IconButton(
            onClick = { 
                renderer.clear()
                onClearClick?.invoke()
            },
            modifier = Modifier
                .align(Alignment.TopEnd)
                .size(24.dp)
        ) {
            androidx.compose.material3.Icon(
                painter = androidx.compose.ui.res.painterResource(android.R.drawable.ic_menu_delete),
                contentDescription = "清除",
                tint = PrimaryBlue.copy(alpha = 0.7f),
                modifier = Modifier.size(16.dp)
            )
        }
        
        // 显示淡色字符提示
        characterData?.let { data ->
            androidx.compose.material3.Text(
                text = data.character,
                fontSize = 80.sp,
                fontWeight = androidx.compose.ui.text.font.FontWeight.Bold,
                color = PrimaryBlue.copy(alpha = 0.15f),
                textAlign = androidx.compose.ui.text.style.TextAlign.Center,
                modifier = Modifier.align(Alignment.Center)
            )
        }
    }
}

/**
 * 低延迟GLSurfaceView
 */
class LowLatencyGLSurfaceView(
    context: Context
) : GLSurfaceView(context) {

    init {
        // 设置OpenGL ES版本
        setEGLContextClientVersion(2)
        
        // 保留EGL上下文以避免重新创建
        preserveEGLContextOnPause = true
    }
}

/**
 * 低延迟书写渲染器
 */
class LowLatencyWritingRenderer(
    private var glView: GLSurfaceView,
    private val context: Context,
    private var characterData: WritingCharacterData? = null,
    private val onWritingComplete: (WritingScoreEvaluator.ScoreResult) -> Unit
) : GLSurfaceView.Renderer {
    
    init {
        // 调试信息：显示字符数据初始化情况
        println("渲染器初始化: 字符=${characterData?.character}, 笔画数=${characterData?.getTotalStrokes()}")
    }

    // OpenGL相关变量

    private var shaderProgram: Int = 0
    private var positionHandle: Int = 0
    private var colorHandle: Int = 0
    private var mvpMatrixHandle: Int = 0
    
    // 视图尺寸
    private var viewWidth = 0
    private var viewHeight = 0
    
    // 矩阵
    private val mvpMatrix = FloatArray(16)
    private val projectionMatrix = FloatArray(16)
    private val viewMatrix = FloatArray(16)
    
    // 书写状态
    private var isWriting = false
    private var currentPath = Path()
    private var allPaths = mutableListOf<Path>()
    private var strokeCount = 0
    private var hasCompletedStrokes = false
    
    // 笔画参考和评分
    private var currentStrokeIndex = 0
    private val scoreEvaluator = WritingScoreEvaluator()
    
    /**
     * 设置GLView引用
     */
    fun setGLView(view: GLSurfaceView) {
        glView = view
    }
    
    /**
     * 更新字符数据
     */
    fun updateCharacterData(newCharacterData: WritingCharacterData?) {
        characterData = newCharacterData
        println("更新字符数据: ${newCharacterData?.character}, 笔画数=${newCharacterData?.getTotalStrokes()}")
        
        // 重置书写状态
        synchronized(this) {
            strokeCount = 0
            hasCompletedStrokes = false
            allPaths.clear()
            completedStrokes.clear()
            currentStrokeVertices.clear()
            currentStrokeWidths.clear()
        }
    }
    
    /**
     * 获取当前笔画索引
     */
    fun getCurrentStrokeIndex(): Int {
        return currentStrokeIndex
    }
    
    /**
     * 移动到下一笔画
     */
    fun moveToNextStroke(): Boolean {
        val totalStrokes = characterData?.getTotalStrokes() ?: 0
        if (currentStrokeIndex < totalStrokes - 1) {
            currentStrokeIndex++
            return true
        }
        return false
    }
    
    // 预估笔画数
    private val estimatedStrokes: Int get() {
        val strokes = characterData?.getTotalStrokes() ?: 5
        println("获取笔画数: 字符=${characterData?.character}, 笔画数=$strokes")
        return strokes
    }
    
    // 动作预测器
    private var motionEventPredictor: MotionEventPredictor? = null
    
    // 顶点缓冲区
    private var vertexBuffer: FloatBuffer? = null
    private var lineVertices = mutableListOf<Float>()
    private var lineWidths = mutableListOf<Float>() // 存储线宽
    private var currentLineWidth = 4.0f // 当前线宽
    
    // 分离的绘制数据
    private var currentStrokeVertices = mutableListOf<Float>()
    private var currentStrokeWidths = mutableListOf<Float>()
    private var completedStrokes = mutableListOf<StrokeData>()
    
    init {
        // 初始化矩阵
        Matrix.setIdentityM(mvpMatrix, 0)
        Matrix.setIdentityM(projectionMatrix, 0)
        Matrix.setIdentityM(viewMatrix, 0)
    }
    
    override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
        // 设置清屏颜色
        GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f)
        
        // 启用抗锯齿
        GLES20.glEnable(GLES20.GL_BLEND)
        GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA)
        
        // 初始化着色器
        initShaders()
        
        // 初始化动作预测器
        motionEventPredictor = MotionEventPredictor.newInstance(glView)
    }
    
    override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
        // 设置视口尺寸
        GLES20.glViewport(0, 0, width, height)
        
        // 更新视图尺寸
        viewWidth = width
        viewHeight = height
    }
    
    override fun onDrawFrame(gl: GL10?) {
        // 清除屏幕
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
        
        // 绘制田字格
        drawGrid()
        
        // 绘制字符参考
        drawCharacterGuide()
        
        // 绘制所有已完成的笔画
        synchronized(this) {
            completedStrokes.forEach { strokeData ->
                drawStrokeWithVariableWidth(strokeData.vertices, strokeData.widths, false)
            }
        }
        
        // 绘制当前正在书写的笔画
        synchronized(this) {
            if (isWriting && currentStrokeVertices.isNotEmpty()) {
                drawStrokeWithVariableWidth(currentStrokeVertices, currentStrokeWidths, true)
            }
        }
    }
    
    /**
     * 初始化着色器
     */
    private fun initShaders() {
        // 顶点着色器代码
        val vertexShaderCode =
            "uniform mat4 uMVPMatrix;" +
            "attribute vec4 vPosition;" +
            "void main() {" +
            "  gl_Position = uMVPMatrix * vPosition;" +
            "}"
        
        // 片段着色器代码
        val fragmentShaderCode =
            "precision mediump float;" +
            "uniform vec4 vColor;" +
            "void main() {" +
            "  gl_FragColor = vColor;" +
            "}"
        
        // 编译顶点着色器
        val vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode)
        
        // 编译片段着色器
        val fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode)
        
        // 创建着色器程序
        shaderProgram = GLES20.glCreateProgram()
        GLES20.glAttachShader(shaderProgram, vertexShader)
        GLES20.glAttachShader(shaderProgram, fragmentShader)
        GLES20.glLinkProgram(shaderProgram)
        
        // 检查着色器程序链接是否成功
        val linkStatus = IntArray(1)
        GLES20.glGetProgramiv(shaderProgram, GLES20.GL_LINK_STATUS, linkStatus, 0)
        if (linkStatus[0] == 0) {
            val log = GLES20.glGetProgramInfoLog(shaderProgram)
            GLES20.glDeleteProgram(shaderProgram)
            throw RuntimeException("着色器程序链接失败: $log")
        }
    }
    
    /**
     * 加载着色器
     */
    private fun loadShader(type: Int, shaderCode: String): Int {
        val shader = GLES20.glCreateShader(type)
        GLES20.glShaderSource(shader, shaderCode)
        GLES20.glCompileShader(shader)
        
        // 检查着色器编译是否成功
        val compileStatus = IntArray(1)
        GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compileStatus, 0)
        if (compileStatus[0] == 0) {
            val log = GLES20.glGetShaderInfoLog(shader)
            GLES20.glDeleteShader(shader)
            throw RuntimeException("着色器编译失败: $log")
        }
        
        return shader
    }
    
    /**
     * 处理触摸事件
     */
    fun handleTouchEvent(event: MotionEvent, width: Int, height: Int): Boolean {
        // 更新视图尺寸
        viewWidth = width
        viewHeight = height
        
        // 使用动作预测器预测触摸事件
        motionEventPredictor?.record(event)
        val predictedEvent = motionEventPredictor?.predict()
        
        // 获取压感值（0.0f到1.0f之间）
        val pressure = event.pressure.coerceIn(0.0f, 1.0f)
        // 根据压感调整线宽（2.0f到8.0f之间）
        currentLineWidth = 2.0f + pressure * 6.0f
        
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                // 开始书写新笔画
                isWriting = true
                currentPath = Path()
                currentPath.moveTo(event.x, event.y)
                
                // 清空当前笔画数据
                synchronized(this) {
                    currentStrokeVertices.clear()
                    currentStrokeWidths.clear()
                    addVertexToCurrentStroke(event.x, event.y, currentLineWidth)
                }
                
                // 请求渲染
                glView.requestRender()
            }
            MotionEvent.ACTION_MOVE -> {
                if (isWriting) {
                    // 添加路径点
                    currentPath.lineTo(event.x, event.y)
                    
                    synchronized(this) {
                        addVertexToCurrentStroke(event.x, event.y, currentLineWidth)
                    }
                    
                    // 使用预测点进行预渲染
                    predictedEvent?.let { predicted ->
                        if (predicted.action == MotionEvent.ACTION_MOVE) {
                            val predictedPressure = predicted.pressure.coerceIn(0.0f, 1.0f)
                            val predictedLineWidth = 2.0f + predictedPressure * 6.0f
                            synchronized(this) {
                                addVertexToCurrentStroke(predicted.x, predicted.y, predictedLineWidth)
                            }
                        }
                    }
                    
                    // 请求渲染
                    glView.requestRender()
                }
            }
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                if (isWriting) {
                    // 结束书写
                    isWriting = false
                    
                    // 将当前笔画保存到已完成笔画列表
                    synchronized(this) {
                        if (currentStrokeVertices.isNotEmpty()) {
                            completedStrokes.add(
                                StrokeData(
                                    vertices = currentStrokeVertices.toList(),
                                    widths = currentStrokeWidths.toList()
                                )
                            )
                        }
                        
                        // 清空当前笔画数据
                        currentStrokeVertices.clear()
                        currentStrokeWidths.clear()
                    }
                    
                    // 创建当前路径的副本
                    val pathCopy = Path(currentPath)
                    allPaths.add(pathCopy)
                    strokeCount++
                    
                    // 调试信息：显示当前笔画数和需要的笔画数
                    println("笔画调试: 当前笔画数=$strokeCount, 需要笔画数=$estimatedStrokes, 字符=${characterData?.character}")
                    
                    // 检查是否完成所有笔画（只有达到所需笔画数才评分）
                    if (strokeCount == estimatedStrokes) {
                        hasCompletedStrokes = true
                        println("笔画调试: 达到所需笔画数，开始评分")
                        // 计算并返回评分
                        evaluateAndReturnScore()
                    } else {
                        println("笔画调试: 还需要 ${estimatedStrokes - strokeCount} 笔")
                    }
                    
                    // 重置当前路径
                    currentPath = Path()
                    
                    // 请求渲染
                    glView.requestRender()
                }
            }
        }
        
        return true
    }
    
    /**
     * 添加顶点到当前笔画
     */
    private fun addVertexToCurrentStroke(x: Float, y: Float, lineWidth: Float) {
        // 将屏幕坐标转换为OpenGL坐标
        // 修复左右镜像问题：反转X轴
        val glX = 1 - (x / viewWidth) * 2
        val glY = 1 - (y / viewHeight) * 2
        
        currentStrokeVertices.add(glX)
        currentStrokeVertices.add(glY)
        currentStrokeVertices.add(0.0f) // Z坐标
        
        // 添加线宽
        currentStrokeWidths.add(lineWidth)
    }
    
    /**
     * 添加顶点到缓冲区（保留用于田字格等）
     */
    private fun addVertex(x: Float, y: Float, lineWidth: Float) {
        // 将屏幕坐标转换为OpenGL坐标
        // 修复左右镜像问题：反转X轴
        val glX = 1 - (x / viewWidth) * 2
        val glY = 1 - (y / viewHeight) * 2
        
        // 使用同步块确保线程安全
        synchronized(this) {
            lineVertices.add(glX)
            lineVertices.add(glY)
            lineVertices.add(0.0f) // Z坐标
            
            // 添加线宽
            lineWidths.add(lineWidth)
            
            // 更新顶点缓冲区
            updateVertexBufferInternal()
        }
    }
    
    /**
     * 更新顶点缓冲区（线程安全版本）
     */
    private fun updateVertexBuffer() {
        synchronized(this) {
            updateVertexBufferInternal()
        }
    }
    
    /**
     * 更新顶点缓冲区（内部实现）
     */
    private fun updateVertexBufferInternal() {
        if (lineVertices.isEmpty()) {
            vertexBuffer = null
            return
        }
        
        // 创建副本以避免并发修改异常
        val verticesCopy = lineVertices.toFloatArray()
        
        val bb = ByteBuffer.allocateDirect(verticesCopy.size * 4)
        bb.order(ByteOrder.nativeOrder())
        vertexBuffer = bb.asFloatBuffer()
        vertexBuffer?.put(verticesCopy)
        vertexBuffer?.position(0)
    }
    
    /**
     * 在Canvas上绘制路径
     */
    private fun drawPathOnCanvas(canvas: Canvas, path: Path, isCurrentPath: Boolean) {
        val paint = Paint().apply {
            color = if (isCurrentPath) PrimaryBlue.toArgb() else Color.BLACK
            style = Paint.Style.STROKE
            strokeWidth = 4f
            isAntiAlias = true
            strokeCap = Paint.Cap.ROUND
            strokeJoin = Paint.Join.ROUND
        }
        
        canvas.drawPath(path, paint)
    }
    
    /**
     * 绘制田字格（蓝绿色虚线）
     */
    private fun drawGrid() {
        // 临时保存当前顶点数据
        val tempVertices: List<Float>
        val tempBuffer: FloatBuffer?
        val tempLineWidths: List<Float>
        
        synchronized(this) {
            tempVertices = lineVertices.toList()
            tempBuffer = vertexBuffer
            tempLineWidths = lineWidths.toList()
            
            // 清空当前顶点数据
            lineVertices.clear()
            lineWidths.clear()
        }
        
        try {
            // 绘制田字格的四条线（虚线效果）
            drawDashedLine(0.1f, 0.5f, 0.9f, 0.5f) // 中间横线
            drawDashedLine(0.5f, 0.1f, 0.5f, 0.9f) // 中间竖线
            
            // 更新顶点缓冲区
            updateVertexBuffer()
            
            // 绘制田字格
            if (lineVertices.size >= 6 && vertexBuffer != null) {
                // 设置视图矩阵
                Matrix.setLookAtM(viewMatrix, 0, 0f, 0f, -3f, 0f, 0f, 0f, 0f, 1f, 0f)
                
                // 计算投影矩阵
                val ratio = viewWidth.toFloat() / viewHeight.toFloat()
                Matrix.frustumM(projectionMatrix, 0, -ratio, ratio, -1f, 1f, 3f, 7f)
                
                // 计算最终的MVP矩阵
                Matrix.multiplyMM(mvpMatrix, 0, projectionMatrix, 0, viewMatrix, 0)
                
                // 添加着色器程序到OpenGL ES环境
                GLES20.glUseProgram(shaderProgram)
                
                // 获取着色器中的变量位置
                positionHandle = GLES20.glGetAttribLocation(shaderProgram, "vPosition")
                colorHandle = GLES20.glGetUniformLocation(shaderProgram, "vColor")
                mvpMatrixHandle = GLES20.glGetUniformLocation(shaderProgram, "uMVPMatrix")
                
                // 启用顶点数组
                GLES20.glEnableVertexAttribArray(positionHandle)
                
                // 准备顶点坐标数据
                vertexBuffer?.position(0)
                GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer)
                
                // 设置绘制颜色（蓝绿色）
                val gridColor = floatArrayOf(0.0f, 0.7f, 0.7f, 0.6f) // 蓝绿色，半透明
                GLES20.glUniform4fv(colorHandle, 1, gridColor, 0)
                
                // 应用投影和视图变换
                GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, mvpMatrix, 0)
                
                // 绘制田字格线条
                GLES20.glLineWidth(1.5f)
                GLES20.glDrawArrays(GLES20.GL_LINES, 0, lineVertices.size / 3)
                
                // 禁用顶点数组
                GLES20.glDisableVertexAttribArray(positionHandle)
            }
        } finally {
            // 恢复当前顶点数据
            synchronized(this) {
                lineVertices.clear()
                lineVertices.addAll(tempVertices)
                lineWidths.clear()
                lineWidths.addAll(tempLineWidths)
                vertexBuffer = tempBuffer
            }
        }
    }
    
    /**
     * 绘制虚线
     */
    private fun drawDashedLine(x1: Float, y1: Float, x2: Float, y2: Float) {
        val dashLength = 0.03f // 虚线段长度
        val gapLength = 0.02f  // 间隔长度
        val totalLength = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))
        
        if (totalLength == 0f) return
        
        val dx = (x2 - x1) / totalLength
        val dy = (y2 - y1) / totalLength
        
        var currentLength = 0f
        var isDash = true
        
        while (currentLength < totalLength) {
            val segmentLength = if (isDash) dashLength else gapLength
            val endLength = minOf(currentLength + segmentLength, totalLength)
            
            if (isDash) {
                val startX = x1 + dx * currentLength
                val startY = y1 + dy * currentLength
                val endX = x1 + dx * endLength
                val endY = y1 + dy * endLength
                
                addVertexForGrid(startX, startY)
                addVertexForGrid(endX, endY)
            }
            
            currentLength = endLength
            isDash = !isDash
        }
    }
    
    /**
     * 绘制字符参考
     */
    private fun drawCharacterGuide() {
        val character = characterData ?: return
        if (character.strokes.isEmpty()) return
        
        // 临时保存当前顶点数据
        val tempVertices: List<Float>
        val tempBuffer: FloatBuffer?
        val tempLineWidths: List<Float>
        
        synchronized(this) {
            tempVertices = lineVertices.toList()
            tempBuffer = vertexBuffer
            tempLineWidths = lineWidths.toList()
            
            // 清空当前顶点数据
            lineVertices.clear()
            lineWidths.clear()
        }
        
        try {
            // 绘制当前笔画参考（如果还没完成所有笔画）
            if (currentStrokeIndex < character.strokes.size) {
                val currentStroke = character.strokes[currentStrokeIndex]
                
                // 将Path转换为顶点数据
                val pathMeasure = PathMeasure(currentStroke.path, false)
                val length = pathMeasure.length
                val points = FloatArray(2)
                val distance = 3f // 每3像素取一个点，提高精度
                
                for (i in 0 until length.toInt() step distance.toInt()) {
                    pathMeasure.getPosTan(i.toFloat(), points, null)
                    // 参考字符坐标已经是归一化的(0-1)，直接使用
                    // 不需要除以viewWidth/viewHeight
                    val normalizedX = points[0]
                    val normalizedY = points[1]
                    addVertexForGuide(normalizedX, normalizedY)
                }
                
                // 更新顶点缓冲区
                updateVertexBuffer()
                
                // 绘制笔画参考
                if (lineVertices.size >= 6 && vertexBuffer != null) {
                    // 设置视图矩阵
                    Matrix.setLookAtM(viewMatrix, 0, 0f, 0f, -3f, 0f, 0f, 0f, 0f, 1f, 0f)
                    
                    // 计算投影矩阵
                    val ratio = viewWidth.toFloat() / viewHeight.toFloat()
                    Matrix.frustumM(projectionMatrix, 0, -ratio, ratio, -1f, 1f, 3f, 7f)
                    
                    // 计算最终的MVP矩阵
                    Matrix.multiplyMM(mvpMatrix, 0, projectionMatrix, 0, viewMatrix, 0)
                    
                    // 添加着色器程序到OpenGL ES环境
                    GLES20.glUseProgram(shaderProgram)
                    
                    // 获取着色器中的变量位置
                    positionHandle = GLES20.glGetAttribLocation(shaderProgram, "vPosition")
                    colorHandle = GLES20.glGetUniformLocation(shaderProgram, "vColor")
                    mvpMatrixHandle = GLES20.glGetUniformLocation(shaderProgram, "uMVPMatrix")
                    
                    // 启用顶点数组
                    GLES20.glEnableVertexAttribArray(positionHandle)
                    
                    // 准备顶点坐标数据
                    vertexBuffer?.position(0)
                    GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer)
                    
                    // 设置绘制颜色（淡蓝色）
                    val guideColor = floatArrayOf(0.3f, 0.6f, 1.0f, 0.4f)
                    GLES20.glUniform4fv(colorHandle, 1, guideColor, 0)
                    
                    // 应用投影和视图变换
                    GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, mvpMatrix, 0)
                    
                    // 绘制笔画参考线条
                    GLES20.glLineWidth(2.5f)
                    GLES20.glDrawArrays(GLES20.GL_LINE_STRIP, 0, lineVertices.size / 3)
                    
                    // 禁用顶点数组
                    GLES20.glDisableVertexAttribArray(positionHandle)
                }
            }
        } finally {
            // 恢复当前顶点数据
            synchronized(this) {
                lineVertices.clear()
                lineVertices.addAll(tempVertices)
                lineWidths.clear()
                lineWidths.addAll(tempLineWidths)
                vertexBuffer = tempBuffer
            }
        }
    }
    
    /**
     * 为笔画参考添加顶点
     */
    private fun addVertexForGuide(x: Float, y: Float) {
        // 将归一化坐标转换为OpenGL坐标
        // 修复左右镜像问题：反转X轴
        val glX = 1 - x * 2
        val glY = 1 - y * 2
        
        synchronized(this) {
            lineVertices.add(glX)
            lineVertices.add(glY)
            lineVertices.add(0.0f) // Z坐标
            
            // 添加线宽
            lineWidths.add(2.0f)
        }
    }
    /**
     * 为田字格添加顶点
     */
    private fun addVertexForGrid(x: Float, y: Float) {
        // 将归一化坐标转换为OpenGL坐标
        // 修复左右镜像问题：反转X轴
        val glX = 1 - x * 2
        val glY = 1 - y * 2
        
        synchronized(this) {
            lineVertices.add(glX)
            lineVertices.add(glY)
            lineVertices.add(0.0f) // Z坐标
            
            // 添加线宽
            lineWidths.add(1.0f)
        }
    }
    /**
     * 绘制具有可变线宽的笔画（真正的压感变化）
     */
    private fun drawStrokeWithVariableWidth(vertices: List<Float>, widths: List<Float>, isCurrentStroke: Boolean) {
        if (vertices.size < 6 || widths.isEmpty()) return
        
        // 设置视图矩阵
        Matrix.setLookAtM(viewMatrix, 0, 0f, 0f, -3f, 0f, 0f, 0f, 0f, 1f, 0f)
        
        // 计算投影矩阵
        val ratio = viewWidth.toFloat() / viewHeight.toFloat()
        Matrix.frustumM(projectionMatrix, 0, -ratio, ratio, -1f, 1f, 3f, 7f)
        
        // 计算最终的MVP矩阵
        Matrix.multiplyMM(mvpMatrix, 0, projectionMatrix, 0, viewMatrix, 0)
        
        // 添加着色器程序到OpenGL ES环境
        GLES20.glUseProgram(shaderProgram)
        
        // 获取着色器中的变量位置
        positionHandle = GLES20.glGetAttribLocation(shaderProgram, "vPosition")
        colorHandle = GLES20.glGetUniformLocation(shaderProgram, "vColor")
        mvpMatrixHandle = GLES20.glGetUniformLocation(shaderProgram, "uMVPMatrix")
        
        // 设置绘制颜色
        val color = if (isCurrentStroke) {
            floatArrayOf(0.0f, 0.47f, 0.95f, 0.9f) // PrimaryBlue，稍微透明
        } else {
            floatArrayOf(0.0f, 0.0f, 0.0f, 0.9f) // Black，稍微透明
        }
        GLES20.glUniform4fv(colorHandle, 1, color, 0)
        
        // 应用投影和视图变换
        GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, mvpMatrix, 0)
        
        // 启用顶点数组
        GLES20.glEnableVertexAttribArray(positionHandle)
        
        // 绘制每个线段，使用对应的线宽
        val pointCount = vertices.size / 3
        val widthCount = widths.size
        
        for (i in 0 until pointCount - 1) {
            // 创建两个点的线段
            val segmentVertices = floatArrayOf(
                vertices[i * 3], vertices[i * 3 + 1], vertices[i * 3 + 2],
                vertices[(i + 1) * 3], vertices[(i + 1) * 3 + 1], vertices[(i + 1) * 3 + 2]
            )
            
            // 创建顶点缓冲区
            val bb = ByteBuffer.allocateDirect(segmentVertices.size * 4)
            bb.order(ByteOrder.nativeOrder())
            val segmentBuffer = bb.asFloatBuffer()
            segmentBuffer.put(segmentVertices)
            segmentBuffer.position(0)
            
            // 准备顶点坐标数据
            GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 0, segmentBuffer)
            
            // 使用当前点的线宽，如果没有对应的线宽则使用默认值
            val currentWidth = if (i < widthCount) {
                widths[i].coerceIn(1.0f, 10.0f)
            } else {
                4.0f
            }
            
            GLES20.glLineWidth(currentWidth)
            GLES20.glDrawArrays(GLES20.GL_LINES, 0, 2)
        }
        
        // 禁用顶点数组
        GLES20.glDisableVertexAttribArray(positionHandle)
    }
    
    /**
     * 平滑顶点数据以减少锯齿
     */
    private fun smoothVertices(vertices: List<Float>): FloatArray {
        if (vertices.size < 9) return vertices.toFloatArray()
        
        val smoothed = mutableListOf<Float>()
        
        // 添加第一个点
        smoothed.addAll(vertices.subList(0, 3))
        
        // 对中间的点进行平滑处理
        for (i in 3 until vertices.size - 3 step 3) {
            val prevX = vertices[i - 3]
            val prevY = vertices[i - 2]
            val currX = vertices[i]
            val currY = vertices[i + 1]
            val nextX = vertices[i + 3]
            val nextY = vertices[i + 4]
            
            // 使用简单的平均平滑
            val smoothX = (prevX + currX + nextX) / 3f
            val smoothY = (prevY + currY + nextY) / 3f
            
            smoothed.add(smoothX)
            smoothed.add(smoothY)
            smoothed.add(0.0f)
        }
        
        // 添加最后一个点
        smoothed.addAll(vertices.subList(vertices.size - 3, vertices.size))
        
        return smoothed.toFloatArray()
    }
    
    private fun drawOpenGL(renderRequest: PathRenderRequest, width: Int, height: Int) {
        // 清除屏幕
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
        
        // 如果没有顶点数据，不进行绘制
        if (lineVertices.size < 6 || vertexBuffer == null) {
            return
        }
        
        // 设置视图矩阵
        Matrix.setLookAtM(viewMatrix, 0, 0f, 0f, -3f, 0f, 0f, 0f, 0f, 1f, 0f)
        
        // 计算投影矩阵
        val ratio = width.toFloat() / height.toFloat()
        Matrix.frustumM(projectionMatrix, 0, -ratio, ratio, -1f, 1f, 3f, 7f)
        
        // 计算最终的MVP矩阵
        Matrix.multiplyMM(mvpMatrix, 0, projectionMatrix, 0, viewMatrix, 0)
        
        // 添加着色器程序到OpenGL ES环境
        GLES20.glUseProgram(shaderProgram)
        
        // 获取着色器中的变量位置
        positionHandle = GLES20.glGetAttribLocation(shaderProgram, "vPosition")
        colorHandle = GLES20.glGetUniformLocation(shaderProgram, "vColor")
        mvpMatrixHandle = GLES20.glGetUniformLocation(shaderProgram, "uMVPMatrix")
        
        // 启用顶点数组
        GLES20.glEnableVertexAttribArray(positionHandle)
        
        // 准备顶点坐标数据
        vertexBuffer?.position(0)
        GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer)
        
        // 设置绘制颜色
        val color = if (renderRequest.isCurrentPath) {
            floatArrayOf(0.0f, 0.47f, 0.95f, 1.0f) // PrimaryBlue
        } else {
            floatArrayOf(0.0f, 0.0f, 0.0f, 1.0f) // Black
        }
        GLES20.glUniform4fv(colorHandle, 1, color, 0)
        
        // 应用投影和视图变换
        GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, mvpMatrix, 0)
        
        // 使用动态线宽绘制线条
        // 由于OpenGL ES 2.0不支持每个顶点的线宽，我们使用平均线宽
        val avgLineWidth = if (lineWidths.isNotEmpty()) {
            lineWidths.average().toFloat()
        } else {
            4.0f
        }
        GLES20.glLineWidth(avgLineWidth)
        GLES20.glDrawArrays(GLES20.GL_LINE_STRIP, 0, lineVertices.size / 3)
        
        // 禁用顶点数组
        GLES20.glDisableVertexAttribArray(positionHandle)
    }
    
    /**
     * 评估并返回评分
     */
    private fun evaluateAndReturnScore() {
        characterData?.let { character ->
            // 调试信息
            println("评分调试: 完成笔画数=${completedStrokes.size}, 需要笔画数=${character.getTotalStrokes()}")
            println("评分调试: 第一笔顶点数=${if(completedStrokes.isNotEmpty()) completedStrokes[0].vertices.size else 0}")
            
            val scoreResult = scoreEvaluator.evaluateWriting(completedStrokes, character)
            
            println("评分调试: 总分=${scoreResult.totalScore}, 重合度=${scoreResult.overlapScore}, 完整度=${scoreResult.completenessScore}")
            
            onWritingComplete(scoreResult)
        }
    }
    
    /**
     * 清除所有路径
     */
    fun clear() {
        synchronized(this) {
            allPaths.clear()
            currentPath = Path()
            lineVertices.clear()
            lineWidths.clear()
            currentStrokeVertices.clear()
            currentStrokeWidths.clear()
            completedStrokes.clear()
            strokeCount = 0
            hasCompletedStrokes = false
            updateVertexBufferInternal()
        }
        requestRender()
    }
    
    /**
     * 请求渲染
     */
    private fun requestRender() {
        // 直接请求GLSurfaceView重新渲染
        // 这将触发onDrawFrame方法的调用
        glView.requestRender()
    }
}

/**
 * 路径渲染请求数据类
 */
data class PathRenderRequest(
    val path: Path,
    val isCurrentPath: Boolean
)

/**
 * 笔画数据类
 */
data class StrokeData(
    val vertices: List<Float>,
    val widths: List<Float>
)